#include "decisiones.h"
#include <QDebug>

decisiones::decisiones()
{
    primeraVez = true;

    for (int i = 0; i < 24; i++) {
        pesosConfianza[i] = (float)(24 - i)/24;
        histograma[i] = (float)1/24;
    }
}

uint32_t decisiones::getPosicionLinea(uint32_t *valoresBarras)
{
    uint32_t medidaPonderada[24];
    uint32_t mediaValores = 0;
    int indexMin = 0;
    int indexMax = 0;

    for (int i = 0; i < 24; i++) {

        if ((i >= 4) && (i <= 19)) {
            medidaPonderada[i] = (valoresBarras[i] + valoresBarras[i+20])/2;
        }else {
            medidaPonderada[i] = valoresBarras[i];
        }

        //Contribuir para la media
        mediaValores += medidaPonderada[i];

        //Obtener mínimo
        if (medidaPonderada[i] < medidaPonderada[indexMin]) {
            indexMin = i;
        }

        //Obtener máximo
        if (medidaPonderada[i] > medidaPonderada[indexMax]) {
            indexMax = i;
        }
    }

    //Dividimos para obtener la media
    mediaValores /= 24;

    return indexMin;

}

uint32_t decisiones::getPosicionLinea2(uint32_t *valoresBarras)
{
    int32_t medidaPonderada[24];
    int32_t mediaValores = 0;
    float confianzaMedia = 0;
    float confianzaMax = 0;
    float indexConfianza = 0;

    for (int i = 0; i < 24; i++) {

        if ((i >= 4) && (i <= 19)) {
            medidaPonderada[i] = (valoresBarras[i] + valoresBarras[i+20])/2;
        }else {
            medidaPonderada[i] = valoresBarras[i];
        }

        //Contribuir para la media
        mediaValores += medidaPonderada[i];
    }

    //Dividimos para obtener la media
    mediaValores /= 24;

    for (int i = 0; i < 24; i++) {
        float confianza = generarConfianza3(medidaPonderada, i, mediaValores);

        confianzaMedia += confianza;

        if (confianza > confianzaMax) {
            confianzaMax = confianza;
            indexConfianza = i;
        }
    }

    confianzaMedia /= 24;
    primeraVez = false;

    centroLineaAnterior = indexConfianza;
    confianzaAnterior = confianzaMax - confianzaMedia;

    return indexConfianza;

}

float decisiones::getPosicionLineaHistogram(uint32_t *valoresBarras, float desplazamiento)
{
    int32_t medidaPonderada[24];
    int32_t mediaValores = 0;
    float histogramaTotal = 0;
    float expandedHistogram[24];


    for (uint32_t i = 0; i < 24; i++) {

        if ((i >= 4) && (i <= 19)) {
            medidaPonderada[i] = (int32_t)((valoresBarras[i] + valoresBarras[i+20])/2);
        }else {
            medidaPonderada[i] = (int32_t)valoresBarras[i];
        }

        //Contribuir para la media
        mediaValores += medidaPonderada[i];

        //Vaciamos el vector de histograma expandido
        expandedHistogram[i] = 0;
    }

    //Dividimos para obtener la media
    mediaValores /= 24;

    //Aplicamos incertidumbre de movimiento
    for (uint32_t i = 0; i < 24; i++) {

        if (i > 1) {
            expandedHistogram[i - 2] += histograma[i]*0.083;
        }

        if (i > 0) {
            expandedHistogram[i - 1] += histograma[i]*0.167;
        }

        expandedHistogram[i] += histograma[i]*0.5;

        if (i < 23) {
            expandedHistogram[i + 1] += histograma[i]*0.167;
        }

        if (i < 22) {
            expandedHistogram[i + 2] += histograma[i]*0.083;
        }

    }

    //Multiplicamos por probabilidad
    for (uint32_t i = 0; i < 24; i++) {
        float probabilidad = generarConfianza4(medidaPonderada, i, mediaValores);

        histograma[i] = expandedHistogram[i] * probabilidad;
        histogramaTotal += histograma[i];
    }

    //Normalizamos las probabilidades
    indexMaxHist = 0;
    for (uint32_t i = 0; i < 24; i++ ){
        histograma[i] /= histogramaTotal;

        if (histograma[i] > histograma[indexMaxHist]) {
            indexMaxHist = i;
        }
    }

    //Calculamos la media
    posicionLinea = 0;

    for (uint32_t i = 0; i < 24; i++) {
        posicionLinea += i*histograma[i];
    }

    hayLinea = (histograma[indexMaxHist] > 0.2);

    return posicionLinea;
}

bool decisiones::getHayLinea()
{
    return hayLinea;
}

float* decisiones::getHistograma()
{
    return histograma;
}

float decisiones::getConfianza()
{
    return confianzaAnterior;
}

float decisiones::generarConfianza(int32_t *valoresBarras, uint32_t indice, int32_t media)
{
    float confianza = (float)media/valoresBarras[indice];

    if (indice > 0) {
        confianza +=  (float)media/valoresBarras[indice-1];
    }

    if (indice < 24) {
        confianza +=  (float)media/valoresBarras[indice+1];
    }

    return confianza;
}

float decisiones::generarConfianza2(int32_t *valoresBarras, uint32_t indice, int32_t media)
{
    float confianza = (float)(media-valoresBarras[indice])/media;

    if (indice > 0) {
        confianza +=  (float)(media-valoresBarras[indice-1])/(2*media);
    }

    if (indice < 24) {
        confianza +=  (float)(media-valoresBarras[indice+1])/(2*media);
    }

    return (confianza > 0.1) ? confianza : 0.1;
}

float decisiones::generarConfianza3(int32_t *valoresBarras, uint32_t indice, int32_t media)
{
    float confianza = (float)(media-valoresBarras[indice])/media;

    if (indice > 0) {
        confianza +=  (float)(media-valoresBarras[indice-1])/(2*media);
    }

    if (indice < 24) {
        confianza +=  (float)(media-valoresBarras[indice+1])/(2*media);
    }

    if ((!primeraVez) && (indice > centroLineaAnterior)) {
        confianza += pesosConfianza[indice - centroLineaAnterior];

    }else if (!primeraVez) {
        confianza += pesosConfianza[centroLineaAnterior - indice];
    }

    return confianza;
}

float decisiones::generarConfianza4(int32_t *valoresBarras, uint32_t indice, int32_t media)
{
    float confianza = (float)(media-valoresBarras[indice]);

    if (indice > 0) {
        confianza +=  (float)(media-valoresBarras[indice-1])/2;
    }

    if (indice < 24) {
        confianza +=  (float)(media-valoresBarras[indice+1])/2;
    }

    return (confianza > (float)0.1) ? confianza :(float)0.1;
}

bool decisiones::hayBifurcacion()
{
//    uint32_t indexMax = 0;
//    uint32_t index2Max = 0;

//    //Buscar los dos puntos con mas probabilidad
//    for (uint32_t i = 0; i < 24; i++) {

//        if (histograma[i] > histograma[index2Max]) {
//            index2Max = i;

//            if (histograma[index2Max] > histograma[indexMax]) {
//                uint32_t aux = index2Max;

//                index2Max = indexMax;
//                indexMax = aux;
//            }
//        }
//    }

//    //Si los indices estan separados, hay una bifurcacion
//    if (indexMax > index2Max) {
//        return ((indexMax - index2Max) > 2);
//    }else {
//        return ((index2Max - indexMax) > 2);
//    }

    //Si los indices estan separados, hay una bifurcacion
    if (indexMaxHist > posicionLinea) {
        return ((indexMaxHist - posicionLinea) > 2);
    }else {
        return ((posicionLinea - indexMaxHist) > 2);
    }
}
